package com.sinosoft.dsp.component.bpm.viewbean;

import java.util.Date;
import java.util.List;

import javax.faces.model.SelectItem;

import org.primefaces.json.JSONObject;
import org.primefaces.model.DefaultTreeNode;

import com.sinosoft.dsp.component.bpm.exception.SinoBPMException;
import com.sinosoft.dsp.component.bpm.facade.engine.ProcessResourceFacade;
import com.sinosoft.dsp.component.bpm.util.BpmImageType;
import com.sinosoft.dsp.component.bpm.util.BpmStatusType;
import com.sinosoft.dsp.platform.components.AbstractEditViewBean;
import com.sinosoft.dsp.platform.utils.SinoManagedBean;
import com.sinosoft.dsp.security.services.SinoAuthenticator;
import com.sinosoft.dsp.security.utils.AuthenticationStatus;
import com.sinosoft.dsp.system.core.exception.SinoException;
import com.sinosoft.dsp.system.to.IGenericTO;
import com.sinosoft.dsp.system.to.attribute.Attribute;
import com.sinosoft.dsp.system.to.helper.ToHelper;
import com.sinosoft.dsp.system.utils.Const;
import com.sinosoft.dsp.system.utils.DateUtils;
import com.sinosoft.dsp.system.utils.JsonUtils;

public class BpmAddEditPackageViewBean extends AbstractEditViewBean implements
		IBpmAddEditPackageViewBean {

	// 包编号(Long)
	public static final String FIELD_PACKAGE_ID = "packageId";

	// 部署ID(Long)
	public static final String FIELD_DEPLOYMENT_ID = "deploymentId";

	// 父包名称和资源
	public static final String FIELD_PARENT_NAME = "parentName";
	public static final String FIELD_PARENT_RESOURCE = "parentResource";

	// 包名称
	public static final String FIELD_PACKAGE_NAME = "packageName";

	// 原始资源名称
	public static final String FIELD_INIT_RESOURCE = "initResourceName";

	// 包描述
	public static final String FIELD_PACKAGE_DESC = "packageDesc";

	// 包对应图标
	public static final String FIELD_PACKAGE_ICON = "packageIcon";

	// 包发布状态
	public static final String FIELD_PACKAGE_STATUS = "packageStatus";

	// 包帮助文档
	public static final String FIELD_PACKAGE_DOC = "packageDoc";

	// 创建者信息
	public static final String FIELD_CREATOR_ID = "creatorId";
	public static final String FIELD_CREATOR = "creator";

	// 创建时间
	public static final String FIELD_CREATE_TIME = "createTime";
	public static final String FIELD_CREATE_TIME_STR = "createTimeStr";

	// 流程最后更新者
	public static final String FIELD_LAST_UPDATOR_ID = "lastUpdatorId";
	public static final String FIELD_LAST_UPDATOR = "lastUpdator";

	// 流程最后更新时间
	public static final String FIELD_LAST_UPDATE_TIME = "lastUpdateTime";
	public static final String FIELD_LAST_UPDATE_TIME_STR = "lastUpdateTimeStr";

	public static final String[] FIELD_STRINGS = new String[] {
			FIELD_PACKAGE_DESC, FIELD_PACKAGE_ICON, FIELD_PACKAGE_STATUS,
			FIELD_PACKAGE_DOC, FIELD_CREATOR_ID, FIELD_CREATOR,
			FIELD_LAST_UPDATOR_ID, FIELD_LAST_UPDATOR };

	public static final String[] FIELD_LONGS = new String[] { FIELD_DEPLOYMENT_ID };

	public static final String[] FIELD_DATES = new String[] {
			FIELD_CREATE_TIME, FIELD_LAST_UPDATE_TIME };

	/**
	 * 转换为JSON对象
	 * 
	 * @return
	 * @throws SinoBPMException
	 */
	@Override
	public JSONObject toJson() throws SinoBPMException {
		try {
			JSONObject jo = new JSONObject();
			// 字符串型
			JsonUtils.putStringAttribute(jo, this.getFields(), FIELD_STRINGS);

			// Long型
			JsonUtils.putLongAttribute(jo, this.getFields(), FIELD_LONGS);

			// Date型
			JsonUtils.putDateAttribute(jo, this.getFields(), FIELD_DATES);

			return jo;
		} catch (Exception e) {
			throw new SinoBPMException("创建JSON对象出现错误。");
		}
	}

	/**
	 * 从JSON对象中设置对象
	 * 
	 * @param jo
	 * @throws SinoBPMException
	 */
	@Override
	public void fromJson(JSONObject jo) throws SinoBPMException {
		try {
			// 字符串型
			JsonUtils.getStringAttribute(this.getFields(), jo, FIELD_STRINGS);

			// Long型
			JsonUtils.getLongAttribute(this.getFields(), jo, FIELD_LONGS);

			// Date型
			JsonUtils.getDateAttribute(this.getFields(), jo, FIELD_DATES);

		} catch (Exception e) {
			throw new SinoBPMException("创建JSON对象出现错误。");
		}
	}

	@Override
	public void init(IGenericTO tos) throws SinoException {
		try {
			IBpmConfigViewBean dirViewBean = (IBpmConfigViewBean) this
					.getParent();
			Attribute<?> sIdAttr = ToHelper.getContentAttriubteByName(tos,
					"selectedId");
			SinoAuthenticator sa = SinoManagedBean
					.findBean("sinoAuthenticator");
			if (sa.getStatus() == AuthenticationStatus.FAILURE) {
				throw new SinoBPMException("请先登录系统");
			}

			// 判断是更新还是添加
			Date now = new Date();
			if (sIdAttr == null || Const.isEmpty(sIdAttr.convertToString())) {

				DefaultTreeNode tn = dirViewBean.getCurrentNode();
				BpmConfigDataObject bdo = (BpmConfigDataObject) tn.getData();

				this.addField(FIELD_DEPLOYMENT_ID, bdo.getDeploymentId());

				this.addField(FIELD_PARENT_NAME, (Const.isEmpty(bdo
						.getResourceName())) ? bdo.getName() : bdo
						.getResourceName());
				this.addField(FIELD_PARENT_RESOURCE, Const.NVL(bdo
						.getResourceName(), ""));

				this.addField(FIELD_CREATE_TIME, now);
				this.addField(FIELD_CREATE_TIME_STR, DateUtils.dat2str(now));

				this.addField(FIELD_CREATOR_ID, sa.getCurrentUser()
						.getUseruuid());
				this.addField(FIELD_CREATOR, sa.getCurrentUser().getFullname());

			} else {
				DefaultTreeNode tn = dirViewBean.getNode(sIdAttr
						.convertToString());
				BpmConfigDataObject bdo = (BpmConfigDataObject) tn.getData();
				if (Const.isEmpty(bdo.getResourceName())) {
					throw new SinoBPMException("不能编辑根节点");
				}

				DefaultTreeNode ptn = dirViewBean.getNode(bdo.getParentId());

				BpmConfigDataObject pdo = (BpmConfigDataObject) ptn.getData();

				ProcessResourceFacade psf = SinoManagedBean
						.findBean("processResourceFacade");
				String resourceName = bdo.getResourceName();
				String re = psf.getDeploymentResource(bdo.getDeploymentId(),
						resourceName);

				if (Const.isEmpty(re)) {
					re = "{}";
				}
				JSONObject reJo = new JSONObject(re);
				fromJson(reJo);

				this.addField(FIELD_PACKAGE_NAME, bdo.getName());

				this.addField(FIELD_INIT_RESOURCE, bdo.getResourceName());

				this.addField(FIELD_DEPLOYMENT_ID, bdo.getDeploymentId());

				this.addField(FIELD_PARENT_NAME, (Const.isEmpty(pdo
						.getResourceName())) ? pdo.getName() : pdo
						.getResourceName());
				this.addField(FIELD_PARENT_RESOURCE, Const.NVL(pdo
						.getResourceName(), ""));

				if (this.getField(FIELD_CREATE_TIME) != null) {
					this.addField(FIELD_CREATE_TIME_STR, DateUtils
							.dat2str((Date) this.getField(FIELD_CREATE_TIME)));
				}

				this.addField(FIELD_LAST_UPDATE_TIME, now);
				this.addField(FIELD_LAST_UPDATE_TIME_STR, DateUtils
						.dat2str(now));

				this.addField(FIELD_LAST_UPDATOR_ID, sa.getCurrentUser()
						.getUseruuid());
				this.addField(FIELD_LAST_UPDATOR, sa.getCurrentUser()
						.getFullname());
			}
		} catch (SinoBPMException e) {
			throw e;
		} catch (Exception e) {
			throw new SinoBPMException("初始化流程包出现错误。");
		}
	}

	public List<SelectItem> getPackageIconItems() {
		return BpmImageType.packageIconItems;
	}

	public List<SelectItem> getPackageStatusItems() {
		return BpmStatusType.getStatusItems();
	}

	public String getPackageIconPath() {
		String icon = (String) this.getField(FIELD_PACKAGE_ICON);

		if (Const.isEmpty(icon)) {
			icon = BpmImageType.defaultPackageIcon;
			this.addField(FIELD_PACKAGE_ICON, icon);
		}
		return BpmImageType.getPackageIconPath(icon);
	}
}
